/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2014年7月18日         Root.Lu
 */

package com.tianci.appstore.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

public class Cache<Key, Value> {
    private ReentrantLock lock = new ReentrantLock();
    private Vector<Key> keys = new Vector<Key>();
    private Vector<Value> values = new Vector<Value>();
    private ConcurrentHashMap<Key, Value> map = new ConcurrentHashMap<Key, Value>();

    public void add(Key key, Value value) {
        lock.lock();
        remove(key);
        keys.add(key);
        values.add(value);
        map.put(key, value);
        lock.unlock();
    }

    public void clear() {
        lock.lock();
        keys.clear();
        values.clear();
        map.clear();
        lock.unlock();
    }

    public void remove(Key key) {
        lock.lock();
        if (containsKey(key)) {
            keys.remove(key);
            Value _value = map.get(key);
            values.remove(_value);
            map.remove(key);
        }
        lock.unlock();
    }

    public Value get(Key key) {
        lock.lock();
        Value ret = map.get(key);
        lock.unlock();
        return ret;
    }

    public Key keyAt(int at) {
        Key ret = null;
        lock.lock();
        try {
            ret = keys.get(at);
        } catch (Exception e) {
            e.printStackTrace();
        }
        lock.unlock();
        return ret;
    }

    public Value valueAt(int at) {
        Value ret = null;
        lock.lock();
        try {
            ret = values.get(at);
        } catch (Exception e) {
            e.printStackTrace();
        }
        lock.unlock();
        return ret;
    }

    public int size() {
        lock.lock();
        int ret = map.size();
        lock.unlock();
        return ret;
    }

    public boolean containsKey(Key key) {
        lock.lock();
        boolean ret = keys.contains(key);
        lock.unlock();
        return ret;
    }

    public boolean containsValue(Value value) {
        lock.lock();
        boolean ret = values.contains(value);
        lock.unlock();
        return ret;
    }

    public List<Key> keys() {
        List<Key> ret = new ArrayList<Key>();
        lock.lock();
        for (Key key : keys)
            ret.add(key);
        lock.unlock();
        return ret;
    }

    public List<Value> values() {
        List<Value> ret = new ArrayList<Value>();
        lock.lock();
        for (Value value : values)
            ret.add(value);
        lock.unlock();
        return ret;
    }
}
